<?php
if(!defined('inside')) die('You do not have permission to execute this file directly.');

/**
* UnitTesting class file.
*
* @author Federico Ramirez <fedekiller@gmail.com>
* @link http://code.google.com/p/akaikiwi/
* @copyright Copyright &copy; 2008-2011 Federico Ramirez
* @license http://www.opensource.org/licenses/mit-license.php MIT Licence
*/

/*
* This class defines a very simple unit testing.
* As akaikiwi is designed to be a lightweight and fast framework for small-to-mid websites,
* if you really need unit testing and you are developing a very big website, you should
* consider using other framework, such as Symfony or Yii.
*/
class UnitTesting {
	private $strict;
	private $enabled;
	private $reports;
	private $format;

	function __construct() {
		$this->strict = FALSE;
		$this->enabled = TRUE;
		$this->reports = array();
		$this->format = NULL;
	}

	/**
	 * Sets whether it should check for strict results
	 * @param boolean $strict
	 */
	public function set_strict($strict) {
		$this->strict = $strict;
	}

	/**
	 * Sets whether to enable or not unit testing
	 * @param boolean $enable
	 */
	public function set_enable($enable) {
		$this->enabled = $enable;
	}

	/**
	 * Sets the format in which to display the tests table
	 * Example:
	 * <table class="my_table">
	 * 	{tr}
	 * </table>
	 *
	 * {tr} will be replaced with actual table rows.
	 * @param unknown_type $format
	 */
	public function set_format($format) {
		$this->format = $format;
	}

	/**
	 * This method will run a new test and return a report array
	 * @param Any $test
	 * @param Any $expeted
	 * @param String $name
	 */
	public function run($test, $expeted, $name = NULL, $store = TRUE) {
		if(!$this->enabled) {
			return TRUE;
		}

		$result = FALSE;
		$expected_type = NULL;
		if(in_array($expeted, array('is_string', 'is_boolean', 'is_true', 'is_false', 'is_true', 'is_integer', 'is_float', 'is_array', 'is_null'), TRUE)) {
			$result = ($expeted($test));

			$expected_type = str_replace(array('true', 'false'), 'boolean', str_replace('is_', '', $expeted));
		} else {
			if($this->strict) {
				$result = ($test === $expeted);
			} else {
				$result = ($test == $expeted);
			}

			$expected_type = gettype($expeted);
		}

		$report = array();
		$report['name'] = $name;
		$report['test_type'] = gettype($test);
		$report['result_type'] = $expected_type;
		$report['result'] = $result;
		$trace = debug_backtrace();
		$report['file'] = $trace[0]['file'];
		$report['line'] = $trace[0]['line'];

		if($store) {
			$this->reports[] = $report;
		}

		return $report;
	}

	/**
	 * Gets all reports
	 */
	public function get_reports() {
		$r = $this->reports;
		$this->reports = array();
		return $r;
	}

	/**
	 * Gets all reports in a HTML table
	 */
	public function show_reports() {
		if($this->format == NULL) {
			$this->format = file_get_contents('akaikiwi/views/unit_testing.php');
		}

		$tr = NULL;
		foreach($this->reports as $report) {
			$tr .= '<tr><td>Nombre</td><td>'.$report['name'].'</td></tr><tr><td>Test Type</td>
			<td>'.$report['test_type'].'</td></tr><tr><td>Result Type</td><td>'.$report['result_type'].
			'</td></tr><tr><td>Result</td><td>'.($report['result'] ? '<font color="green">PASSED</font>' : '<font color="red">NOT PASSED</font>').'</td></tr><tr><td>File</td>
			<td>'.$report['file'].'</td></tr><tr><td>Line</td><td>'.$report['line'].'</td></tr>
			<tr><td></td><td></td></tr>';
		}

		$content = str_replace('{tr}', $tr, $this->format);
		return $content;
	}
}
